#ifndef __EVENT__H__
#define __EVENT__H__

#include "collaboration.h"

#define DEFAULT_EVENT_TYPE 0

typedef CORBA::Any GenericObject; /**< Oculta el uso del tipo Any de CORBA */
typedef CORBA::Long PortableInteger; /**< Oculta el uso del tipo Long de CORBA */
typedef CORBA::LongLong PortableLong; /**< Oculta el uso del tipo LongLong de CORBA */
typedef CORBA::Float PortableFloat; /**< Oculta el uso del tipo Float de CORBA */
typedef CORBA::Double PortableDouble; /**< Oculta el uso del tipo Double de CORBA */

/**
* @brief Clase que modela un evento generico
* @author Carlos Rodriguez Dominguez
*
* Esta clase se utilizara para modelar los diversos eventos
* que se usaran en el sistema. Cada evento debera tener una serie
* de campos creados mediante "create_member". Los listeners se
* encargaran de captar unos u otros eventos realizando los tests
* que consideren pertinentes mediante las funciones "exists_member",
* "member_value", "count_members", etc. Por defecto contiene un
* campo llamado "type" donde se guarda el tipo de evento especifico,
* que permitira tambien establecer filtros mediante listeners.
* Por defecto tiene un campo llamado "type" que contendra inicialmente
* el valor definido por DEFAULT_EVENT_TYPE. Este campo permitira diferenciar
* unos tipos de eventos de otros. Se usan los tipos de datos siguientes
* para denominar los tipos primitivos del lenguaje: PortableInteger,
* PortableLong, PortableFloat y PortableDouble. A estos tipos se les
* puede realizar un "casting" a int, long, float y double, respectivamente.
*/
class Event {
private:
	collaboration::Event* event; /**< Estructura que modela un evento */
	
	/**
	* Posicion de un campo del evento
	*
	* @param name Nombre del campo
	* @return Posicion del campo o -1 si no existe
	*/
	int member_pos(const char* name);
	
	/**
	* Crea un nuevo campo de tipo generico para el evento
	*
	* @param name Nombre del campo
	* @param value Valor del campo
	*/
	void create_member(const char* name, const GenericObject& value);
	
public:	
	/**
	* Constructor por defecto. Crea un campo llamado "type",
	* cuyo valor inicial es el definido por DEFAULT_EVENT_TYPE.
	*/
	Event();
	
	/**
	* Destructor
	*/
	virtual ~Event();
	
	/**
	* Comprueba si un campo existe o no en el evento
	*
	* @param name Nombre del campo
	* @return True si el campo existe. False en caso contrario.
	*/
	bool exists_member(const char* name);
	
	/**
	* Obtiene el valor de un campo (si existe)
	*
	* @param name Nombre del campo
	* @param exists Booleano donde se indica si el campo existe o no
	* @return Tipo generico que modela el valor del campo especificado o
	*         valor nulo si el campo no existe
	*/
	GenericObject member_value(const char* name, bool& exists);
	
	/**
	* Obtiene el valor de un campo (si existe)
	*
	* @param name Nombre del campo
	* @return Tipo generico que modela el valor del campo especificado o
	*         valor nulo si el campo no existe
	*/
	GenericObject member_value(const char* name);
	
	/**
	* Asigna un valor a un campo (crea el campo si no existe)
	*
	* @param name Nombre del campo
	* @param value Valor para el campo
	*/
	void member_value(const char* name, const GenericObject& value);
	
	/**
	* Asigna un valor a un campo (crea el campo si no existe)
	*
	* @param name Nombre del campo
	* @param value Valor para el campo
	*/
	void member_value(const char* name, PortableInteger value);
	
	/**
	* Asigna un valor a un campo (crea el campo si no existe)
	*
	* @param name Nombre del campo
	* @param value Valor para el campo
	*/
	void member_value(const char* name, PortableLong value);
	
	/**
	* Asigna un valor a un campo (crea el campo si no existe)
	*
	* @param name Nombre del campo
	* @param value Valor para el campo
	*/
	void member_value(const char* name, PortableFloat value);
	
	/**
	* Asigna un valor a un campo (crea el campo si no existe)
	*
	* @param name Nombre del campo
	* @param value Valor para el campo
	*/
	void member_value(const char* name, PortableDouble value);
	
	/**
	* Asigna un valor a un campo (crea el campo si no existe)
	*
	* @param name Nombre del campo
	* @param value Valor para el campo
	*/
	void member_value(const char* name, const char* value);
	
	/**
	* Cuenta el numero de campos del evento
	*
	* @return Numero de campos del evento
	*/
	int count_members();
	
	/**
	* Obtiene el tipo concreto del evento
	*
	* @return Tipo del evento definido por el campo "type".
	*/
	PortableInteger get_type();
	
	/**
	* Convierte el evento en un objeto generico
	*
	* @param data Variable generica donde se guardara el evento
	*/
	void to_any(GenericObject& data);
	
	/**
	* Extrae un evento de un objeto generico
	*
	* @param data Variable generica desde donde se extrae el evento
	* @return True si pudo convertirse. False en caso contrario.
	*/
	bool from_any(const GenericObject& data);
};

#endif
